WebGLãŠããã©ãŒã ãããã¡ãªããžã§ã¯ã(UBO)ã®ã¢ã©ã€ã¡ã³ãèŠä»¶ãšãæ§ã ãªãã©ãããã©ãŒã ã§ã·ã§ãŒããŒæ§èœãæå€§åããããã®ãã¹ããã©ã¯ãã£ã¹ã培åºè§£èª¬ã
WebGLã·ã§ãŒããŒãŠããã©ãŒã ãããã¡ã®ã¢ã©ã€ã¡ã³ãïŒããã©ãŒãã³ã¹ã®ããã®ã¡ã¢ãªã¬ã€ã¢ãŠãæé©å
WebGLã«ãããŠããŠããã©ãŒã ãããã¡ãªããžã§ã¯ãïŒUBOïŒã¯ã倧éã®ããŒã¿ãå¹ççã«ã·ã§ãŒããŒã«æž¡ãããã®åŒ·åãªã¡ã«ããºã ã§ããããããæ§ã ãªããŒããŠã§ã¢ããã©ãŠã¶å®è£ éã§ã®äºææ§ãšæé©ãªããã©ãŒãã³ã¹ã確ä¿ããããã«ã¯ãUBOããŒã¿ãæ§é åããéã«ç¹å®ã®ã¢ã©ã€ã¡ã³ãèŠä»¶ãçè§£ããéµå®ããããšã極ããŠéèŠã§ãããããã®ã¢ã©ã€ã¡ã³ãèŠåãç¡èŠãããšãäºæãã¬åäœãã¬ã³ããªã³ã°ãšã©ãŒããããŠèããããã©ãŒãã³ã¹ã®äœäžã«ã€ãªããå¯èœæ§ããããŸãã
ãŠããã©ãŒã ãããã¡ãšã¢ã©ã€ã¡ã³ãã®çè§£
ãŠããã©ãŒã ãããã¡ã¯ãGPUã®ã¡ã¢ãªäžã«ååšããã¡ã¢ãªãããã¯ã§ãããã·ã§ãŒããŒããã¢ã¯ã»ã¹ã§ããŸãããããã¯ãç¹ã«å€æè¡åããããªã¢ã«ããããã£ãã©ã€ããã©ã¡ãŒã¿ã®ãããªå€§èŠæš¡ãªããŒã¿ã»ãããæ±ãéã«ãåã ã®uniform倿°ãããå¹ççãªä»£æ¿ææ®µãæäŸããŸããUBOã®å¹çæ§ã®éµã¯ãåäžã®ãŠããããšããŠæŽæ°ã§ããèœåã«ãããããã«ããåã ã®uniformæŽæ°ã®ãªãŒããŒããããåæžãããŸãã
ã¢ã©ã€ã¡ã³ããšã¯ãããŒã¿åãæ ŒçŽãããªããã°ãªããªãã¡ã¢ãªã¢ãã¬ã¹ãæããŸããããŒã¿åããšã«ç°ãªãã¢ã©ã€ã¡ã³ããå¿ èŠã§ãããããã«ããGPUãå¹ççã«ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããããšãä¿èšŒãããŸããWebGLã¯ãOpenGL ESããã¢ã©ã€ã¡ã³ãèŠä»¶ãç¶æ¿ããŠãããããã¯ããã«åºç€ãšãªãããŒããŠã§ã¢ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®æ £ç¿ã«åºã¥ããŠããŸãããããã®èŠä»¶ã¯ãå€ãã®å ŽåãããŒã¿åã®ãµã€ãºã«ãã£ãŠæ±ºå®ãããŸãã
ã¢ã©ã€ã¡ã³ããéèŠãªçç±
äžé©åãªã¢ã©ã€ã¡ã³ãã¯ãããã€ãã®åé¡ãåŒãèµ·ããå¯èœæ§ããããŸãïŒ
- æªå®çŸ©ã®åäœïŒ GPUãuniform倿°ã®å¢çå€ã®ã¡ã¢ãªã«ã¢ã¯ã»ã¹ããå¯èœæ§ããããäºæž¬äžèœãªåäœãåŒãèµ·ãããã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ãããå¯èœæ§ããããŸãã
- ããã©ãŒãã³ã¹ã®äœäžïŒ ã¢ã©ã€ã¡ã³ãããããããŒã¿ã¢ã¯ã»ã¹ã¯ãGPUã«æ£ããããŒã¿ãååŸããããã®äœåãªã¡ã¢ãªã¢ã¯ã»ã¹ã匷å¶ããã¬ã³ããªã³ã°æ§èœã«èãã圱é¿ãäžããå¯èœæ§ããããŸããããã¯ãGPUã®ã¡ã¢ãªã³ã³ãããŒã©ãç¹å®ã®ã¡ã¢ãªå¢çã§ã®ããŒã¿ã¢ã¯ã»ã¹ã«æé©åãããŠããããã§ãã
- äºææ§ã®åé¡ïŒ ããŒããŠã§ã¢ãã³ããŒããã©ã€ãã®å®è£ ã«ãã£ãŠãã¢ã©ã€ã¡ã³ãããããããŒã¿ã®æ±ãã¯ç°ãªãå ŽåããããŸããããããã€ã¹ã§æ£ããåäœããã·ã§ãŒããŒãã埮åŠãªã¢ã©ã€ã¡ã³ãã®éãã«ããå¥ã®ããã€ã¹ã§ã¯å€±æããå¯èœæ§ããããŸãã
WebGLã®ã¢ã©ã€ã¡ã³ãèŠå
WebGLã¯ãUBOå ã®ããŒã¿åã«å¯ŸããŠç¹å®ã®ã¢ã©ã€ã¡ã³ãèŠåã矩åä»ããŠããŸãããããã®èŠåã¯éåžžãã€ãåäœã§è¡šçŸãããäºææ§ãšããã©ãŒãã³ã¹ã確ä¿ããããã«äžå¯æ¬ ã§ãã以äžã«ãæãäžè¬çãªããŒã¿åãšãã®èŠæ±ãããã¢ã©ã€ã¡ã³ãã®å èš³ã瀺ããŸãïŒ
float,int,uint,boolïŒ 4ãã€ãã¢ã©ã€ã¡ã³ãvec2,ivec2,uvec2,bvec2ïŒ 8ãã€ãã¢ã©ã€ã¡ã³ãvec3,ivec3,uvec3,bvec3ïŒ 16ãã€ãã¢ã©ã€ã¡ã³ãïŒéèŠïŒ ããŒã¿ã¯12ãã€ãããå«ã¿ãŸããããvec3/ivec3/uvec3/bvec3ã¯16ãã€ãã¢ã©ã€ã¡ã³ããèŠæ±ããŸããããã¯ããããæ··ä¹±ã®åå ã§ããïŒvec4,ivec4,uvec4,bvec4ïŒ 16ãã€ãã¢ã©ã€ã¡ã³ã- è¡åïŒ
mat2,mat3,mat4ïŒïŒ ã«ã©ã ã¡ãžã£ãŒé ã§ãååã¯vec4ãšããŠã¢ã©ã€ã¡ã³ããããŸãããããã£ãŠãmat2ã¯32ãã€ãïŒ2å * 16ãã€ãïŒãmat3ã¯48ãã€ãïŒ3å * 16ãã€ãïŒãmat4ã¯64ãã€ãïŒ4å * 16ãã€ãïŒãå æããŸãã - é åïŒ é åã®åèŠçŽ ã¯ããã®ããŒã¿åã®ã¢ã©ã€ã¡ã³ãèŠåã«åŸããŸããããŒã¹ãšãªãåã®ã¢ã©ã€ã¡ã³ãã«ãã£ãŠã¯ãèŠçŽ éã«ããã£ã³ã°ãååšããå ŽåããããŸãã
- æ§é äœïŒ æ§é äœã¯æšæºã¬ã€ã¢ãŠãèŠåã«åŸã£ãŠã¢ã©ã€ã¡ã³ããããåã¡ã³ããŒã¯èªèº«ã®èªç¶ãªã¢ã©ã€ã¡ã³ãã«é 眮ãããŸãããŸããæ§é äœã®ãµã€ãºãæå€§ã¡ã³ããŒã®ã¢ã©ã€ã¡ã³ãã®åæ°ã«ãªãããã«ãæ§é äœã®æ«å°Ÿã«ããã£ã³ã°ã远å ãããããšããããŸãã
Standardã¬ã€ã¢ãŠã vs. Sharedã¬ã€ã¢ãŠã
OpenGLïŒãããŠãã®å»¶é·ç·äžã«ããWebGLïŒã¯ããŠããã©ãŒã ãããã¡ã«å¯ŸããŠäž»ã«2ã€ã®ã¬ã€ã¢ãŠããstandardã¬ã€ã¢ãŠããšsharedã¬ã€ã¢ãŠããå®çŸ©ããŠããŸããWebGLã¯éåžžãããã©ã«ãã§standardã¬ã€ã¢ãŠãã䜿çšããŸããsharedã¬ã€ã¢ãŠãã¯æ¡åŒµæ©èœçµç±ã§å©çšå¯èœã§ããããµããŒããéãããŠããããWebGLã§ã¯åºã䜿çšãããŠããŸãããstandardã¬ã€ã¢ãŠãã¯ãç°ãªããã©ãããã©ãŒã éã§ç§»æ€æ§ã®é«ããæç¢ºã«å®çŸ©ãããã¡ã¢ãªã¬ã€ã¢ãŠããæäŸããŸããäžæ¹ãsharedã¬ã€ã¢ãŠãã¯ããã³ã³ãã¯ããªãããã³ã°ãå¯èœã§ãããç§»æ€æ§ã¯äœããªããŸããæå€§éã®äºææ§ãåŸãããã«ã¯ãstandardã¬ã€ã¢ãŠãã䜿çšããŠãã ããã
å®è·µçãªäŸãšã³ãŒããã¢
ãããã®ã¢ã©ã€ã¡ã³ãèŠåããå®è·µçãªäŸãšã³ãŒãã¹ããããã§èª¬æããŸãããããŠããã©ãŒã ãããã¯ãå®çŸ©ããããã«GLSLïŒOpenGL Shading LanguageïŒããUBOããŒã¿ãèšå®ããããã«JavaScriptã䜿çšããŸãã
äŸ1ïŒåºæ¬çãªã¢ã©ã€ã¡ã³ã
GLSLïŒã·ã§ãŒããŒã³ãŒãïŒïŒ
layout(std140) uniform ExampleBlock {
float value1;
vec3 value2;
float value3;
};
JavaScriptïŒUBOããŒã¿ã®èšå®ïŒïŒ
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// Calculate the size of the uniform buffer
const bufferSize = 4 + 16 + 4; // float (4) + vec3 (16) + float (4)
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// Create a Float32Array to hold the data
const data = new Float32Array(bufferSize / 4); // Each float is 4 bytes
// Set the data
data[0] = 1.0; // value1
// Padding is needed here. value2 starts at offset 4, but needs to be aligned to 16 bytes.
// This means we need to explicitly set the elements of the array, accounting for padding.
data[4] = 2.0; // value2.x (offset 16, index 4)
data[5] = 3.0; // value2.y (offset 20, index 5)
data[6] = 4.0; // value2.z (offset 24, index 6)
data[7] = 5.0; // value3 (offset 32, index 8)
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
解説ïŒ
ãã®äŸã§ã¯ãvalue1ã¯floatïŒ4ãã€ãïŒãvalue2ã¯vec3ïŒããŒã¿12ãã€ãïŒãvalue3ã¯ããäžã€ã®floatïŒ4ãã€ãïŒã§ããstd140ã¬ã€ã¢ãŠãèŠåã«ãããvalue2ã¯16ãã€ãå¢çã«ã¢ã©ã€ã¡ã³ããããå¿
èŠããããŸãããã®ããããªãã»ãã0ã®`value1`ïŒ4ãã€ãïŒã®åŸã«ããã£ã³ã°ãæ¿å
¥ããã`value2`ã¯ãªãã»ãã16ããå§ãŸããŸãã`value3`ã¯ãã®åŸã®ãªãã»ãã28ããå§ãŸããŸãããããã¯å
šäœã®ãµã€ãºã¯æå€§ã®ã¡ã³ããŒã®ã¢ã©ã€ã¡ã³ãïŒ16ãã€ãïŒã®åæ°ã§ãªããã°ãªããªããããåèšãµã€ãºã¯32ãã€ãã«ãªããŸãã`value2`ãæ£ãã16ãã€ãå¢çã«ã¢ã©ã€ã¡ã³ãããããã®ããã£ã³ã°ã極ããŠéèŠã§ããJavaScripté
åãäœæãããããã£ã³ã°ãèæ
®ããŠã€ã³ããã¯ã¹ãæå®ãããŠããç¹ã«æ³šæããŠãã ãããæ£ããããã£ã³ã°ããªããšãäžæ£ç¢ºãªããŒã¿ãèªã¿åãããšã«ãªããŸãã
äŸ2ïŒè¡åã®æ±ã
GLSLïŒã·ã§ãŒããŒã³ãŒãïŒïŒ
layout(std140) uniform MatrixBlock {
mat4 modelMatrix;
mat4 viewMatrix;
};
JavaScriptïŒUBOããŒã¿ã®èšå®ïŒïŒ
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// Calculate the size of the uniform buffer
const bufferSize = 64 + 64; // mat4 (64) + mat4 (64)
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// Create a Float32Array to hold the matrix data
const data = new Float32Array(bufferSize / 4); // Each float is 4 bytes
// Create sample matrices (column-major order)
const modelMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
const viewMatrix = new Float32Array([
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
]);
// Set the model matrix data
for (let i = 0; i < 16; ++i) {
data[i] = modelMatrix[i];
}
// Set the view matrix data (offset by 16 floats, or 64 bytes)
for (let i = 0; i < 16; ++i) {
data[i + 16] = viewMatrix[i];
}
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
解説ïŒ
åmat4è¡åã¯4ã€ã®vec4åã§æ§æãããŠããããã64ãã€ããå æããŸããmodelMatrixã¯ãªãã»ãã0ããå§ãŸããviewMatrixã¯ãªãã»ãã64ããå§ãŸããŸããè¡åã¯OpenGLããã³WebGLã§ã®æšæºã§ããã«ã©ã ã¡ãžã£ãŒé ã§æ ŒçŽãããŸããåžžã«JavaScripté
åãäœæããŠããå€ã代å
¥ããããšãå¿ããªãã§ãã ãããããã«ãããããŒã¿ã®åãFloat32ãšããŠç¶æããã`bufferSubData`ãæ£ããæ©èœããŸãã
äŸ3ïŒUBOå ã®é å
GLSLïŒã·ã§ãŒããŒã³ãŒãïŒïŒ
layout(std140) uniform LightBlock {
vec4 lightColors[3];
};
JavaScriptïŒUBOããŒã¿ã®èšå®ïŒïŒ
const gl = canvas.getContext('webgl');
const buffer = gl.createBuffer();
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
// Calculate the size of the uniform buffer
const bufferSize = 16 * 3; // vec4 * 3
gl.bufferData(gl.UNIFORM_BUFFER, bufferSize, gl.DYNAMIC_DRAW);
// Create a Float32Array to hold the array data
const data = new Float32Array(bufferSize / 4);
// Light Colors
const lightColors = [
[1.0, 0.0, 0.0, 1.0],
[0.0, 1.0, 0.0, 1.0],
[0.0, 0.0, 1.0, 1.0],
];
for (let i = 0; i < lightColors.length; ++i) {
data[i * 4 + 0] = lightColors[i][0];
data[i * 4 + 1] = lightColors[i][1];
data[i * 4 + 2] = lightColors[i][2];
data[i * 4 + 3] = lightColors[i][3];
}
gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
解説ïŒ
lightColorsé
åå
ã®åvec4èŠçŽ ã¯16ãã€ããå æããŸãããŠããã©ãŒã ãããã¯ã®åèšãµã€ãºã¯16 * 3 = 48ãã€ãã§ããé
åèŠçŽ ã¯ããããããåºæ¬åã®ã¢ã©ã€ã¡ã³ãã«åãããŠå¯ã«ããã¯ãããŸããJavaScripté
åã«ã¯ãã©ã€ãã®è²ããŒã¿ã«åŸã£ãŠå€ãèšå®ãããŸããã·ã§ãŒããŒå
ã®lightColorsé
åã®åèŠçŽ ã¯vec4ãšããŠæ±ãããJavaScriptã§ãåæ§ã«ãã¹ãŠã®èŠçŽ ãåããå¿
èŠãããããšãå¿ããªãã§ãã ããã
ã¢ã©ã€ã¡ã³ãåé¡ã®ãããã°çšããŒã«ãšãã¯ããã¯
ã¢ã©ã€ã¡ã³ãã®åé¡ãæ€åºããã®ã¯é£ããå ŽåããããŸãã以äžã«åœ¹ç«ã€ããŒã«ãšãã¯ããã¯ãããã€ã玹ä»ããŸãïŒ
- WebGL InspectorïŒ Spector.jsã®ãããªããŒã«ã䜿çšãããšããŠããã©ãŒã ãããã¡ã®å å®¹ãæ€æ»ãããã®ã¡ã¢ãªã¬ã€ã¢ãŠããèŠèŠåã§ããŸãã
- ã³ã³ãœãŒã«ãã°ïŒ ã·ã§ãŒããŒå ã§uniform倿°ã®å€ãåºåããJavaScriptããæž¡ããŠããããŒã¿ãšæ¯èŒããŸããäžäžèŽãããã°ãã¢ã©ã€ã¡ã³ãã®åé¡ã瀺ããŠããå¯èœæ§ããããŸãã
- GPUãããã¬ïŒ RenderDocã®ãããªã°ã©ãã£ãã¯ã¹ãããã¬ã¯ãGPUã¡ã¢ãªã®äœ¿çšç¶æ³ãã·ã§ãŒããŒã®å®è¡ã«é¢ããè©³çŽ°ãªæ å ±ãæäŸã§ããŸãã
- ãã€ããªæ€æ»ïŒ é«åºŠãªãããã°ã®ããã«ãUBOããŒã¿ããã€ããªãã¡ã€ã«ãšããŠä¿åããããã¯ã¹ãšãã£ã¿ã§æ€æ»ããŠæ£ç¢ºãªã¡ã¢ãªã¬ã€ã¢ãŠãã確èªããããšãã§ããŸããããã«ãããããã£ã³ã°ã®äœçœ®ãã¢ã©ã€ã¡ã³ããèŠèŠçã«ç¢ºèªã§ããŸãã
- æŠç¥çãªããã£ã³ã°ïŒ 確信ãæãŠãªãå Žåã¯ãæ§é äœã«æç€ºçã«ããã£ã³ã°ã远å ããŠãæ£ããã¢ã©ã€ã¡ã³ãã確ä¿ããŸããããã«ããUBOã®ãµã€ãºããããã«å¢å ãããããããŸãããã埮åŠã§ãããã°ãå°é£ãªåé¡ãåé¿ã§ããŸãã
- GLSL `offsetof`ïŒ GLSLã®`offsetof`颿°ïŒGLSLããŒãžã§ã³4.50以éãå¿ èŠã§ãäžéšã®WebGLæ¡åŒµæ©èœã§ãµããŒããããŠããŸãïŒã䜿çšãããšããŠããã©ãŒã ãããã¯å ã®ã¡ã³ããŒã®ãã€ããªãã»ãããåçã«æ±ºå®ã§ããŸããããã¯ãã¬ã€ã¢ãŠãã®çè§£ã確èªããäžã§éåžžã«äŸ¡å€ããããŸãããã ãããã®å©çšå¯èœæ§ã¯ãã©ãŠã¶ãããŒããŠã§ã¢ã®ãµããŒãã«ãã£ãŠå¶éãããå ŽåããããŸãã
UBOã®ããã©ãŒãã³ã¹ãæé©åããããã®ãã¹ããã©ã¯ãã£ã¹
ã¢ã©ã€ã¡ã³ã以å€ã«ããUBOã®ããã©ãŒãã³ã¹ãæå€§åããããã«ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããïŒ
- é¢é£ããŒã¿ãã°ã«ãŒãåããïŒ é »ç¹ã«äœ¿çšãããuniform倿°ãåãUBOã«é 眮ããŠããããã¡ã®ãã€ã³ãã£ã³ã°åæ°ãæå°éã«æããŸãã
- UBOã®æŽæ°ãæå°éã«ããïŒ UBOã¯å¿ èŠãªå Žåã«ã®ã¿æŽæ°ããŸããé »ç¹ãªUBOã®æŽæ°ã¯ãé倧ãªããã©ãŒãã³ã¹ã®ããã«ããã¯ã«ãªãå¯èœæ§ããããŸãã
- ãããªã¢ã«ããšã«åäžã®UBOã䜿çšããïŒ å¯èœã§ããã°ããã¹ãŠã®ãããªã¢ã«ããããã£ãåäžã®UBOã«ãŸãšããŸãã
- ããŒã¿ã®å±ææ§ãèæ ®ããïŒ ã·ã§ãŒããŒã§ã®äœ¿ç𿹿³ãåæ ããé åºã§UBOã®ã¡ã³ããŒãé 眮ããŸããããã«ããããã£ãã·ã¥ã®ãããçãåäžããå¯èœæ§ããããŸãã
- ãããã¡ã€ã«ãšãã³ãããŒã¯ïŒ ãããã¡ã€ãªã³ã°ããŒã«ã䜿çšããŠãUBOã®äœ¿çšã«é¢é£ããããã©ãŒãã³ã¹ã®ããã«ããã¯ãç¹å®ããŸãã
é«åºŠãªãã¯ããã¯ïŒã€ã³ã¿ãŒãªãŒãããŒã¿
äžéšã®ã·ããªãªãç¹ã«ããŒãã£ã¯ã«ã·ã¹ãã ãè€éãªã·ãã¥ã¬ãŒã·ã§ã³ãæ±ãå ŽåãUBOå ã§ããŒã¿ãã€ã³ã¿ãŒãªãŒãããããšããã©ãŒãã³ã¹ãåäžããããšããããŸããããã¯ãã¡ã¢ãªã¢ã¯ã»ã¹ãã¿ãŒã³ãæé©åããæ¹æ³ã§ããŒã¿ãé 眮ããããšãå«ã¿ãŸããããšãã°ããã¹ãŠã®`x`座æšããŸãšããŠæ ŒçŽããæ¬¡ã«ãã¹ãŠã®`y`座æšãæ ŒçŽããã®ã§ã¯ãªãã`x1, y1, z1, x2, y2, z2...`ã®ããã«ã€ã³ã¿ãŒãªãŒããããããšããããŸããããã«ãããã·ã§ãŒããŒãããŒãã£ã¯ã«ã®`x`ã`y`ã`z`æåã«åæã«ã¢ã¯ã»ã¹ããå¿ èŠãããå Žåã«ããã£ãã·ã¥ã®ã³ããŒã¬ã³ã·ãåäžããŸãã
ãã ããã€ã³ã¿ãŒãªãŒããããããŒã¿ã¯ã¢ã©ã€ã¡ã³ãã®èæ ®äºé ãè€éã«ããå¯èœæ§ããããŸããåã€ã³ã¿ãŒãªãŒãèŠçŽ ãé©åãªã¢ã©ã€ã¡ã³ãèŠåã«æºæ ããŠããããšã確èªããŠãã ããã
ã±ãŒã¹ã¹ã¿ãã£ïŒã¢ã©ã€ã¡ã³ãã®ããã©ãŒãã³ã¹ãžã®åœ±é¿
ã¢ã©ã€ã¡ã³ãã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ã説æããããã«ãæ¶ç©ºã®ã·ããªãªãèããŠã¿ãŸãããã倿°ã®ãªããžã§ã¯ãããããããããã倿è¡åãå¿ èŠãšããã·ãŒã³ãèããŸãã倿è¡åãUBOå ã§é©åã«ã¢ã©ã€ã¡ã³ããããŠããªãå ŽåãGPUã¯åãªããžã§ã¯ãã®è¡åããŒã¿ãååŸããããã«è€æ°ã®ã¡ã¢ãªã¢ã¯ã»ã¹ãå®è¡ããå¿ èŠããããããããŸãããããã¯ãç¹ã«ã¡ã¢ãªåž¯åå¹ ãéãããŠããã¢ãã€ã«ããã€ã¹ã§ãèããããã©ãŒãã³ã¹ã®äœäžã«ã€ãªããå¯èœæ§ããããŸãã
å¯Ÿç §çã«ãè¡åãé©åã«ã¢ã©ã€ã¡ã³ããããŠããã°ãGPUã¯åäžã®ã¡ã¢ãªã¢ã¯ã»ã¹ã§å¹ççã«ããŒã¿ãååŸã§ãããªãŒããŒããããåæžããã¬ã³ããªã³ã°ããã©ãŒãã³ã¹ãåäžãããŸãã
å¥ã®ã±ãŒã¹ã¯ã·ãã¥ã¬ãŒã·ã§ã³ã§ããå€ãã®ã·ãã¥ã¬ãŒã·ã§ã³ã§ã¯ã倿°ã®ããŒãã£ã¯ã«ã®äœçœ®ãšéåºŠãæ ŒçŽããå¿ èŠããããŸããUBOã䜿çšãããšããããã®å€æ°ãå¹ççã«æŽæ°ããããŒãã£ã¯ã«ãã¬ã³ããªã³ã°ããã·ã§ãŒããŒã«éä¿¡ã§ããŸãããã®ãããªç¶æ³ã§ã¯ãæ£ããã¢ã©ã€ã¡ã³ããäžå¯æ¬ ã§ãã
ã°ããŒãã«ãªèæ ®äºé ïŒããŒããŠã§ã¢ãšãã©ã€ãã®å·®ç°
WebGLã¯ç°ãªããã©ãããã©ãŒã éã§äžè²«ããAPIãæäŸããããšãç®æããŠããŸãããUBOã®ã¢ã©ã€ã¡ã³ãã«åœ±é¿ãäžããããŒããŠã§ã¢ããã©ã€ãã®å®è£ ã«ã¯åŸ®åŠãªéããååšããå¯èœæ§ããããŸããäºææ§ã確ä¿ããããã«ã¯ãããŸããŸãªããã€ã¹ããã©ãŠã¶ã§ã·ã§ãŒããŒããã¹ãããããšãéèŠã§ãã
ããšãã°ãã¢ãã€ã«ããã€ã¹ã¯ãã¹ã¯ãããã·ã¹ãã ãããã¡ã¢ãªå¶çŽãå³ããå Žåããããã¢ã©ã€ã¡ã³ããããã«éèŠã«ãªããŸããåæ§ã«ãGPUãã³ããŒã«ãã£ãŠã¢ã©ã€ã¡ã³ãèŠä»¶ããããã«ç°ãªãå ŽåããããŸãã
å°æ¥ã®ååïŒWebGPUãšãã®å
Webã°ã©ãã£ãã¯ã¹ã®æªæ¥ã¯WebGPUã§ããããã¯WebGLã®éçã«å¯ŸåŠããææ°ã®GPUããŒããŠã§ã¢ãžã®ãã坿¥ãªã¢ã¯ã»ã¹ãæäŸããããã«èšèšãããæ°ããAPIã§ããWebGPUã¯ã¡ã¢ãªã¬ã€ã¢ãŠããšã¢ã©ã€ã¡ã³ãã«å¯Ÿããããæç€ºçãªå¶åŸ¡ãæäŸããéçºè ãããã©ãŒãã³ã¹ãããã«æé©åã§ããããã«ããŸããWebGLã§ã®UBOã¢ã©ã€ã¡ã³ããçè§£ããããšã¯ãWebGPUã«ç§»è¡ãããã®é«åºŠãªæ©èœã掻çšããããã®åŒ·åºãªåºç€ãšãªããŸãã
WebGPUã§ã¯ãã·ã§ãŒããŒã«æž¡ãããããŒã¿æ§é ã®ã¡ã¢ãªã¬ã€ã¢ãŠããæç€ºçã«å¶åŸ¡ã§ããŸããããã¯ãæ§é äœãš`[[offset]]`屿§ã䜿çšããŠå®çŸãããŸãã`[[offset]]`屿§ã¯ãæ§é äœå ã®ã¡ã³ããŒã®ãã€ããªãã»ãããæå®ããŸããWebGPUã¯ãŸããè¡åã®`layout(row_major)`ã`layout(column_major)`ãªã©ãæ§é äœã®å šäœçãªã¬ã€ã¢ãŠããæå®ãããªãã·ã§ã³ãæäŸããŸãããããã®æ©èœã«ãããéçºè ã¯ã¡ã¢ãªã¢ã©ã€ã¡ã³ããšãããã³ã°ã«å¯ŸããŠãã¯ããã«ãã现ããå¶åŸ¡ãå¯èœã«ãªããŸãã
çµè«
WebGLã®UBOã¢ã©ã€ã¡ã³ãèŠåãçè§£ããéµå®ããããšã¯ãæé©ãªã·ã§ãŒããŒããã©ãŒãã³ã¹ãéæããç°ãªããã©ãããã©ãŒã éã§ã®äºææ§ã確ä¿ããããã«äžå¯æ¬ ã§ããUBOããŒã¿ãæ éã«æ§é åãããã®èšäºã§èª¬æãããããã°ãã¯ããã¯ã䜿çšããããšã§ãäžè¬çãªèœãšã穎ãé¿ããWebGLã®æœåšèœåãæå€§éã«åŒãåºãããšãã§ããŸãã
ã¢ã©ã€ã¡ã³ãé¢é£ã®åé¡ãç¹å®ã解決ããããã«ãåžžã«ããŸããŸãªããã€ã¹ããã©ãŠã¶ã§ã·ã§ãŒããŒããã¹ãããããšãåªå ããŠãã ãããWebã°ã©ãã£ãã¯ã¹æè¡ãWebGPUãšå ±ã«é²åããã«ã€ããŠããããã®æ žãšãªãååããã£ãããšçè§£ããããšã¯ã髿§èœã§èŠèŠçã«é åçãªWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«åŒãç¶ãéèŠã§ãã